﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once
#include "GcmpGeometryInterface.h"
#include "CurveCurveIntersectTypes.h"
#include "CurveSurfaceIntersectTypes.h"
#include "SurfaceSurfaceIntersectTypes.h"
#include "ICurve2dCoincidenceData.h"
#include "ICurve3dCoincidenceData.h"
#include "ICurveSurfaceCoincidenceData.h"
#include "ICurve2dCurve2dIntersection.h"
#include "ICurve3dCurve3dIntersection.h"
#include "ICurve3dSurfaceIntersection.h"
#include "ISurfaceSurfaceIntersection.h"
#include "GbmpConstants.h"
#include "GcmpApiDeclaration.h"

namespace gcmp
{
    class Vector3d;
    class Intervald;
    class ICurve2d;
    class ISurface;
    class ILine3d;
    class IPlane;
    class IPolygon;
    class IFace;
    class IBody;
    class ICurveBodyIntersection;
    
    /// \brief 几何求交类，用于几何对象的求交计算
    ///
    class GCMP_GEOMETRY_INTERFACE_EXPORT AlgorithmIntersect
    {
    public:
        /// \brief 两条二维曲线求交
        ///
        /// \param pFirstCurve2d         第一条二维曲线
        /// \param pSeccondCurve2d       第二条二维曲线
        /// \param opIntersects          求交结果
        /// \param distanceEpsilon       距离容差
        /// \return 相交返回true，不相交返回false
        static bool Intersect(const ICurve2d *pFirstCurve2d, const ICurve2d *pSeccondCurve2d, std::vector<OwnerPtr<ICurve2dCurve2dIntersection>> &opIntersects, double distanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        
        /// \brief 两条三维曲线求交
        ///
        /// \param pFirstCurve2d         第一条三维曲线
        /// \param pSeccondCurve2d       第二条三维曲线
        /// \param opIntersects          求交结果
        /// \param distanceEpsilon       距离容差
        /// \return 相交返回true，不相交返回false
        static bool Intersect(const ICurve3d *pFirstCurve2d, const ICurve3d *pSeccondCurve2d, std::vector<OwnerPtr<ICurve3dCurve3dIntersection>> &opIntersects, double distanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        
        /// \brief 三维曲线和几何曲面求交
        ///
        /// \param pCurve3d         三维曲线
        /// \param pSurface         几何曲面
        /// \param opIntersects     求交结果
        /// \param distanceEpsilon  距离容差
        /// \return 相交返回true，不相交返回false
        static bool Intersect(const ICurve3d *pCurve3d, const ISurface *pSurface, std::vector<OwnerPtr<ICurve3dSurfaceIntersection>> &opIntersects, double distanceEpsilon = Constants::DISTANCE_ITERATION_EPS);


        /// \brief 两个几何曲面求交
        ///
        /// \param pFirstSurface         第一个几何曲面
        /// \param pSecondSurface        第二个几何曲面
        /// \param trimIntersectCurveOutOfSurfaceDomain 对交线超出曲面参数域的部分进行裁剪
        /// \param opIntersects          求交结果
        /// \param distanceEpsilon       距离容差
        /// \return 相交返回true，不相交返回false
        static bool Intersect(const ISurface *pFirstSurface, const ISurface *pSecondSurface, bool trimIntersectCurveOutOfSurfaceDomain,std::vector<OwnerPtr<ISurfaceSurfaceIntersection>> &opIntersects, double distanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        
        /// \brief 二维曲线与多边形求交（如有叫返回二维曲线在多边形内部的部分）
        ///
        /// \param pCurve                        二维曲线
        /// \param pPolygon                      多边形
        /// \param isKeepCurveOnPolygon          如果曲线和多边形上的某条边重合，是否需要返回
        /// \param opIntersects                  求交结果（二维曲线上的区间段)
        /// \param distanceEpsilon               距离容差
        /// \return 相交返回true，不相交返回false
        static bool Intersect(const ICurve2d *pCurve, const IPolygon *pPolygon, bool isKeepCurveOnPolygon, std::vector<Intervald>& opIntersects, double distanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief 计算拓扑面和三维曲线的交点（返回距离最近的交点）
        ///
        /// \param pFace                                 拓扑面
        /// \param pCurve3d                              三维曲线
        /// \param minimalDistanceIntersectPointOnFace   拓扑面上的点
        /// \param int& iRealIntersect                   Edge参与-2/平行-1/默认0/内部1/边界2/
        /// \param distanceEpsilon                       距离容差
        /// \return  相交返回true，不相交返回false
        static bool Intersect(const IFace* pFace, const ICurve3d* pCurve3d, Vector3d &minimalDistanceIntersectPointOnFace, int& iRealIntersect, double distanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief 三维直线和平面求交
        ///
        /// \param pLine3d         三维直线
        /// \param pPlane         平面
        /// \param intersectPoint     求交结果
        /// \return 相交返回true，不相交返回false
        static bool Intersect(const ILine3d *pLine3d, const IPlane *pPlane, Vector3d& intersectPoint);

        /// \brief 计算三维曲线和体外壳的所有交点并按交点参数值升序排序，重合段记录起始点和终止点
        /// \param[in] pCurve                          三维曲线,不能为空,否则报错
        /// \param[in] pBody                               体,不能为空,否则报错
        /// \param[out] intersects    交点集合(按在曲线上参数升序排列),不能为空,否则报错
        /// \param[in] distanceEpsilon                                   容差,数值大小缺省为Constants::DISTANCE_ITERATION_EPS=1e-4
        /// \return 曲线和体是否有交点,true有,false没有
        static bool Intersect(const ICurve3d* pCurve, const IBody* pBody, std::vector<OwnerPtr<ICurveBodyIntersection>> &intersects, double distanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief 两个几何曲面求交
        ///
        /// \param pFirstSurface         第一个几何曲面
        /// \param pSecondSurface        第二个几何曲面
        /// \param opIntersects          求交结果
        /// \param distanceEpsilon       距离容差
        /// \return 相交返回true，不相交返回false
        GCMP_OBSOLETE_API(2020 / 5 / 9, AlgorithmIntersect::Intersect(const ISurface*, const ISurface*, bool,std::vector<OwnerPtr<ISurfaceSurfaceIntersection>>&, double)) static bool Intersect(const ISurface *pFirstSurface, const ISurface *pSecondSurface, std::vector<OwnerPtr<ISurfaceSurfaceIntersection>> &opIntersects, double distanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

    };
}
